<?php

namespace util;


class Page
{
    protected $firstRow;            // 起始行数
    protected $listRows;            // 列表每页显示行数
    protected $parameter;           // 分页跳转时要带的参数
    protected $totalRows;           // 总行数
    protected $totalPages;          // 分页总页面数
    protected $rollPage   = 10;     // 分页栏每页显示的页数
    protected $lastSuffix = true;   // 最后一页是否显示总页数
    protected $hasMore;             // 是否有下一页
    protected $lastPage;            // 最后一页
    protected $total;               // 数据总数

    private $p       = 'page';  // 分页参数名
    private $url     = '';      // 当前链接URL
    private $nowPage = 1;       // 当前页码

    public function __construct($totalRows, $listRows = 10, $parameter = [], $url = '')
    {
        /* 基础设置 */
        $this->totalRows  = $totalRows; // 设置总记录数
        $this->listRows   = $listRows;  // 设置每页显示行数
        $this->parameter  = empty($parameter) ? $_GET : $parameter;
        $this->nowPage    = empty($_GET[$this->p]) ? 1 : intval($_GET[$this->p]);
        $this->nowPage    = $this->nowPage > 0 ? $this->nowPage : 1;
        $this->firstRow   = $this->listRows * ($this->nowPage - 1);
        $this->url        = !empty($url) ? $url : $this->url;
        $this->lastPage   = ceil($totalRows / $listRows);
        $this->hasMore    = $this->nowPage < $this->lastPage;
    }

    private function getUrl($page)
    {
        $url_param  = '';
        $page_param = '';
        if (!empty($this->parameter)) {
            $i = 0;
            foreach ($this->parameter as $k=>$v) {
                if ($k != $this->p) {
                    $joint_str  = ($i == 0) ? '?' : '&';
                    $url_param .= $joint_str . $k . '=' . urlencode($v);
                    $i++;
                } else {
                    $page_param = '&' . $k . '=' . (int)$page;
                }
            }
        }
        $page_param = !empty($page_param) ? $page_param : '&' . $this->p . '=' . (int)$page;
        $url = $this->url . $url_param . $page_param;
        return $url;
    }

    /**
     * 上一页按钮
     * @param string $text
     * @return string
     */
    protected function getPreviousButton($text = '«')
    {
        if ($this->nowPage <= 1) {
            return $this->getDisabledTextWrapper($text);
        }

        $url = $this->getUrl($this->nowPage - 1);

        return $this->getPageLinkWrapper($url, $text);
    }

    /**
     * 下一页按钮
     * @param string $text
     * @return string
     */
    protected function getNextButton($text = '»')
    {
        if (!$this->hasMore) {
            return $this->getDisabledTextWrapper($text);
        }

        $url = $this->getUrl($this->nowPage + 1);

        return $this->getPageLinkWrapper($url, $text);
    }

    /**
     * 数据是否足够分页
     * @access public
     * @return boolean
     */
    public function hasPages()
    {
        return !(1 == $this->nowPage && !$this->hasMore);
    }

    // 获取数字连接
    public function getLinks()
    {
        $block = [
            'first'  => null,
            'slider' => null,
            'last'   => null
        ];

        $side   = 3;
        $window = $side * 2;

        if ($this->lastPage < $window + 6) {
            $block['first'] = $this->getUrlRange(1, $this->lastPage);
        } elseif ($this->nowPage <= $window) {
            $block['first'] = $this->getUrlRange(1, $window + 2);
            $block['last']  = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
        } elseif ($this->nowPage > ($this->lastPage - $window)) {
            $block['first'] = $this->getUrlRange(1, 2);
            $block['last']  = $this->getUrlRange($this->lastPage - ($window + 2), $this->lastPage);
        } else {
            $block['first']  = $this->getUrlRange(1, 2);
            $block['slider'] = $this->getUrlRange($this->nowPage - $side, $this->nowPage + $side);
            $block['last']   = $this->getUrlRange($this->lastPage - 1, $this->lastPage);
        }

        $html = '';

        if (is_array($block['first'])) {
            $html .= $this->getUrlLinks($block['first']);
        }

        if (is_array($block['slider'])) {
            $html .= $this->getDots();
            $html .= $this->getUrlLinks($block['slider']);
        }

        if (is_array($block['last'])) {
            $html .= $this->getDots();
            $html .= $this->getUrlLinks($block['last']);
        }

        return $html;
    }

    /**
     * 渲染分页html
     * @return mixed
     */
    public function render()
    {
        if ($this->hasPages()) {
            return sprintf(
                '<ul class="pagination">%s %s %s</ul>',
                $this->getPreviousButton(),
                $this->getLinks(),
                $this->getNextButton()
            );
        }
    }

    /**
     * 批量生成页码按钮.
     * @param  array $urls
     * @return string
     */
    protected function getUrlLinks(array $urls)
    {
        $html = '';

        foreach ($urls as $page => $url) {
            $html .= $this->getPageLinkWrapper($url, $page);
        }

        return $html;
    }

    /**
     * 创建一组分页链接
     * @access public
     * @param  int $start
     * @param  int $end
     * @return array
     */
    public function getUrlRange($start, $end)
    {
        $urls = [];

        for ($page = $start; $page <= $end; $page++) {
            $urls[$page] = $this->getUrl($page);
        }

        return $urls;
    }

    /**
     * 生成省略号按钮
     * @return string
     */
    protected function getDots()
    {
        return $this->getDisabledTextWrapper('...');
    }

    /**
     * 生成一个禁用的按钮
     * @param  string $text 按钮显示内容
     * @return string
     */
    protected function getDisabledTextWrapper($text)
    {
        return '<li class="disabled"><span>' . $text . '</span></li>';
    }

    /**
     * 生成一个激活的按钮
     * @param  string $text
     * @return string
     */
    protected function getActivePageWrapper($text)
    {
        return '<li class="active"><span>' . $text . '</span></li>';
    }

    /**
     * 生成一个可点击的按钮
     * @param  string $url
     * @param  int    $page
     * @return string
     */
    protected function getAvailablePageWrapper($url, $page)
    {
        return '<li><a href="' . htmlentities($url) . '">' . $page . '</a></li>';
    }

    /**
     * 生成普通页码按钮
     * @param  string $url
     * @param  int    $page
     * @return string
     */
    protected function getPageLinkWrapper($url, $page)
    {
        if ($page == $this->nowPage) {
            return $this->getActivePageWrapper($page);
        }

        return $this->getAvailablePageWrapper($url, $page);
    }

}
